/**   
* @Title: Analyze.java 
* @Package com.sllx.xmlanalyze 
* @Description: TODO
* @author  
* @date 2014-2-28 下午11:19:43 
* @version V1.0   
*/
package com.sllx.xmlanalyze;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

/** 
 * 版权所有(C)2013-2023 
 * 公司名称：
 * 公司地址：
 * 网址:
 * 版本:
 * 文件名：com.sllx.xmlanalyze.Analyze.java 
 * 作者: 疏楼龙宿
 * 创建时间: 2014-2-28下午11:19:43  
 * 负责人:  
 * 修改者：  
 * 修改时间：2014-2-28下午11:19:43 
 */


/** 
 * @className_interfaceName: Analyze 
 * @date 2014-2-28 下午11:19:43 
 * @author 张斌
 * @Description: TODO 
 */
public class Analyze {
	private   static Map<String, Object> beanInstanceMap;
	private   static List<Element> childElements;
	private   static Analyze analyze; 
	private   static String xmlPath;
	
	/*
	 * 构造器私有化
	 */
	private Analyze(String xml_Path){
		xmlPath = xml_Path;
		try {
			//初始化时执行注入
			this.doAnalyze();
		} catch (InstantiationException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		} catch (IllegalArgumentException e) {
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			e.printStackTrace();
		} catch (NoSuchMethodException e) {
			e.printStackTrace();
		} catch (SecurityException e) {
			e.printStackTrace();
		} catch (DocumentException e) {
			e.printStackTrace();
		}
	}
	
	/*
	 * 获取xml中节点组成的list
	 */
	@SuppressWarnings("unchecked")
	private  void getElemList() throws DocumentException {
		SAXReader reader = new SAXReader();
		//加载xml
		Document document = reader.read(this.getClass().getResourceAsStream(xmlPath));
		Element root = document.getRootElement();
		//获取节点数组
		childElements = root.elements("bean");
		if(childElements==null||childElements.size()==0){
			System.out.println("未发现节点");
		}
	}
	
	/*
	 * 创建实例
	 */
	private void createInstances() throws InstantiationException, IllegalAccessException, ClassNotFoundException {
		if(beanInstanceMap==null || beanInstanceMap.size()==0) beanInstanceMap = new HashMap<String, Object>();
		for (Element child : childElements) {
			String bean_id = child.attributeValue("id");
			String bean_class = child.attributeValue("class");
			//beanid对应实例，存入HashMap
			beanInstanceMap.put(bean_id, Class.forName(bean_class).newInstance());
		}
	}
	
	/*
	 *根据beanId获取实例
	 */
	private  Object getInstance(String beanId) throws InstantiationException, IllegalAccessException, ClassNotFoundException{
		return beanInstanceMap.get(beanId);
	}
	
	/*
	 * 构建setter方法名
	 */
	private  String createSetterMethodName(String propertyId){
		return "set" + propertyId.substring(0,1).toUpperCase() + propertyId.substring(1);
	}
	
	/*
	 * 执行注入,被执行的set方法必须只有一个参数,该方法不可重载。
	 */
	private  void invokeMethod( String methodName, Object obj, Object param) throws ClassNotFoundException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException{
		//通过方法名与参数列表定位方法
		Method method = null;
		try{
			method = obj.getClass().getMethod(methodName, param.getClass().getInterfaces());
		} catch(NoSuchMethodException e){
			//获取obj中所有的方法
			Method[] methods = obj.getClass().getMethods();
			//传入参数的全部接口或父类
			Class<?>[] interfaces = param.getClass().getInterfaces();
			for(Method met  : methods){
				//筛选出方法名对应的方法
				 if(met.getName().equals(methodName)){
					 //获取方法的第一个参数类型
					Class<?> methodParamType = met.getParameterTypes()[0];
					for(Class<?> c : interfaces){
						//如果当前参数接口是方法形参类型的子类,满足方法执行要求
						if(methodParamType.isAssignableFrom(c)){
							met.invoke(obj, param);
							return;
						}
					}
				 }
			}
		}
		
		//执行obj中的method方法，参数为param
		method.invoke(obj, param);
	}
	
	/*
	 * 核心方法
	 */
	private void doAnalyze() throws DocumentException, InstantiationException, IllegalAccessException, ClassNotFoundException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException{
		//获取节点数组
		getElemList();
		//创建实例
		createInstances();
		for (Element child : childElements) {
			String beanId = child.attributeValue("id");
			List<Element> properties = child.elements("property");
			//若没有property属性，表示为最最底层。
			if(properties.size()==0) break;
			//获取当前bean的实例
			Object objForBean = getInstance(beanId);
			for(Element element : properties){
				String propertyName = element.attributeValue("name");
				String propertyRef = element.attributeValue("ref");
				//获取property对应的实例
				Object objForProp = getInstance(propertyRef);
				String methodName =createSetterMethodName(propertyName);
				invokeMethod(methodName, objForBean, objForProp);
			}
		}
	}
	
	/*
	 * 实例化
	 */
	public static Analyze getAnalyzeInstance(String xmlPath){
		if(analyze==null){
			analyze =  new Analyze(xmlPath);
			return analyze;
		} else {
			return analyze;
		}
	}
	
	/*
	 * 获取实例化对象
	 */
	public Object getBean(String beanId){
		return beanInstanceMap.get(beanId);
	}
}
